/*
 * @(#)AlarmServiceImpl.java 2009-11-12
 * 
 * Copy Right@ wumi
 */

package com.mstore.service.alarm;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.util.concurrent.ThreadPoolExecutor;

import javax.mail.MessagingException;

import javax.mail.internet.MimeMessage;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;

import com.mstore.util.TimeWatcher;

/**
 * <pre>
 * 系统报警服务实现
 * 
 * @author xiongfei
 * 
 * @version 0.9
 * 
 * 修改版本: 0.9
 * 修改日期: 2009-11-12
 * 修改人 :  xiongfei
 * 修改说明: 初步完成
 * 复审人 ：
 * </pre>
 */
public class AlarmServiceImpl  implements AlarmService {

	/**
	 * 发件人
	 */
	private String from;

	/**
	 * 收件人
	 */
	private String to;

	/**
	 * email发送器
	 */
	private JavaMailSenderImpl mailSender;

	/**
	 * 计时器
	 */
	private TimeWatcher timeWatcher = new TimeWatcher(30000);

	/**
	 * 邮件发送线程池
	 */
	private ThreadPoolExecutor executor;

	/**
	 * 日志对象
	 */
	private static final Logger log = LoggerFactory
			.getLogger(AlarmServiceImpl.class);

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.mstore.service.alarm.AlarmService#sendMessage(java.lang.String,
	 * java.lang.String, java.lang.String)
	 */
	public void sendMessage(final String host, final String subject,
			final String text) {

		executor.execute(new Runnable() {

			public void run() {
				String sub = subject;
				if (StringUtils.isNotBlank(host)) {
					sub = subject + " 来自主机: " + host;
				}

				try {
					SimpleMailMessage message = new SimpleMailMessage();
					message.setFrom(from);
					message.setTo(to.split("\\s*,\\s*"));
					message.setSubject(sub);
					message.setText(text);
					timeWatcher.watch();
					mailSender.send(message);
				} catch (Exception e) {
					log.error("发送邮件异常", e);
				}
			}
		});

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.mstore.service.alarm.AlarmService#sendMessage(java.lang.String,
	 * java.lang.String)
	 */
	public void sendMessage(String subject, String text) {
		sendMessage(subject, text, (Exception) null);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.mstore.service.alarm.AlarmService#sendMessage(java.lang.String,
	 * java.lang.String, java.lang.Throwable)
	 */
	public void sendMessage(final String subject, final String text,
			final Throwable ex) {
		executor.execute(new Runnable() {

			public void run() {
				String sub = subject;
				String txt = text;
				try {
					SimpleMailMessage message = new SimpleMailMessage();
					message.setFrom(from);
					message.setTo(to.split("\\s*,\\s*"));
					try {
						String address = InetAddress.getLocalHost()
								.getHostName();
						if (address != null) {
							sub = subject + " 来自主机: " + address;
						}
					} catch (Exception e) {
					}
					message.setSubject(sub);

					if (ex != null) {
						StringWriter sw = new StringWriter();
						PrintWriter pw = new PrintWriter(sw);
						try {
							ex.printStackTrace(pw);
							txt += "\r\n" + sw.toString();
						} finally {
							try {
								sw.close();
								pw.close();
							} catch (IOException e) {
							}
						}
					}
					message.setText(txt);
					timeWatcher.watch();
					mailSender.send(message);
				} catch (Exception e) {
					log.error("发送邮件异常", to, e);
				}
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.mstore.service.alarm.AlarmService#sendMessage(java.lang.String,
	 * java.lang.String, java.lang.String, java.lang.Throwable)
	 */
	public void sendMessage(final String to, final String subject,
			final String text, final Throwable ex) {
		executor.execute(new Runnable() {

			public void run() {
				String sub = subject;
				String txt = text;
				try {
					SimpleMailMessage message = new SimpleMailMessage();
					message.setFrom(from);
					message.setTo(to.split("\\s*,\\s*"));
					message.setCc(AlarmServiceImpl.this.to.split("\\s*,\\s*"));
					try {
						String address = InetAddress.getLocalHost()
								.getHostName();
						if (address != null) {
							sub = subject + " 来自主机: " + address;
						}
					} catch (Exception e) {
					}
					message.setSubject(sub);

					if (ex != null) {
						StringWriter sw = new StringWriter();
						PrintWriter pw = new PrintWriter(sw);
						try {
							ex.printStackTrace(pw);
							txt += "\r\n" + sw.toString();
						} finally {
							try {
								sw.close();
								pw.close();
							} catch (IOException e) {
							}
						}
					}
					message.setText(txt);
					timeWatcher.watch();
					mailSender.send(message);
				} catch (Exception e) {
					log.error("发送邮件异常", e);
				}
			}
		});
	}

	/**
	 * 给某人发邮件并抄送给某人
	 * 
	 * @param subject
	 *            主题
	 * @param text
	 *            内容
	 * @param to
	 *            收件人
	 * @param cc
	 *            抄送人
	 */
	protected void sendMessageToSomeBody(final String subject,
			final String text, final String to, final String cc) {
		executor.execute(new Runnable() {

			public void run() {
				String sub = subject;
				try {
					try {
						String address = InetAddress.getLocalHost()
								.getHostName();
						if (address != null) {
							sub = subject + " 来自主机: " + address;
						}
					} catch (Exception e) {
					}
					SimpleMailMessage message = new SimpleMailMessage();
					message.setFrom(from);
					message.setTo(to.split("\\s*,\\s*"));
					if (cc != null) {
						message.setCc(cc.split("\\s*,\\s*"));
					}
					message.setSubject(sub);
					message.setText(text);
					timeWatcher.watch();
					mailSender.send(message);
				} catch (Exception e) {
					log.error("发送邮件异常", e);
				}
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.mstore.service.alarm.AlarmService#sendMimeMessage(java.lang.String,
	 * java.lang.String)
	 */
	public void sendMimeMessage(String subject, String text) {
		sendMimeMessage(subject, text, this.to);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.mstore.service.alarm.AlarmService#sendMimeMessage(java.lang.String,
	 * java.lang.String, java.lang.String)
	 */
	public void sendMimeMessage(final String subject, final String text,
			final String to) {

		executor.execute(new Runnable() {

			public void run() {

				String s = subject;

				try {
					try {
						String address = InetAddress.getLocalHost().getHostName();
						if (address != null) {
							//s = subject+address;
						log.info("adderss="+address);
						log.info("host"+InetAddress.getLocalHost());
						}
					} catch (Exception e) {
						log.error("获得主机名出错",e.getMessage());
					}
					final String sub = s;
					timeWatcher.watch();
					mailSender.send(new MimeMessagePreparator() {

						public void prepare(MimeMessage mimeMessage)
								throws MessagingException {
							MimeMessageHelper message = new MimeMessageHelper(
									mimeMessage, true, mailSender
											.getDefaultEncoding());
							message.setFrom(from);
							message.setTo(to.split("\\s*,\\s*"));
							message.setSubject(sub);
							message.setText(text, true);
						}
					});
				} catch (Exception e) {
					log.error("发送邮件异常", e);
				}
			}
		});
	}

	

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.mstore.service.alarm.AlarmService#getAdminEmails()
	 */
	public String getAdminEmails() {
		return to;
	}

	public String getFrom() {
		return from;
	}

	public void setFrom(String from) {
		this.from = from;
	}

	public String getTo() {
		return to;
	}

	public void setTo(String to) {
		this.to = to;
	}

	public JavaMailSenderImpl getMailSender() {
		return mailSender;
	}

	public void setMailSender(JavaMailSenderImpl mailSender) {
		this.mailSender = mailSender;
	}

	public ThreadPoolExecutor getExecutor() {
		return executor;
	}

	public void setExecutor(ThreadPoolExecutor executor) {
		this.executor = executor;
	}

}
